/*
	Copyright 2009 Omer Saatcioglu
	Licensed under the Apache License, Version 2.0 (the "License");
	you may not use this file except in compliance with the License.
	You may obtain a copy of the License at

		http://www.apache.org/licenses/LICENSE-2.0

	Unless required by applicable law or agreed to in writing, software
	distributed under the License is distributed on an "AS IS" BASIS,
	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
	See the License for the specific language governing permissions and
	limitations under the License.

	$Author$
	$Revision$
	$LastChangedDate$
   
*/

package com.saatcioglu.android.guessthenumber;

import java.util.ArrayList;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ListActivity;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.SystemClock;
import android.os.Vibrator;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Chronometer;
import android.widget.EditText;
import android.widget.TextView;
import android.graphics.Color;

public class GfxGuesstheNumber extends ListActivity implements OnClickListener, OnLongClickListener{
	
	static final private int NEWGAME_ID = Menu.FIRST;
    static final private int SHOWMETHENUMBER_ID = Menu.FIRST + 1;
    static final private int ABOUT_ID = Menu.FIRST + 3;
    static final private int EXIT_ID = Menu.FIRST + 4;
    
    private ArrayList<String> mStrings = new ArrayList<String>();
    private ArrayAdapter<String> mAdapter;
    private Vibrator vibrator;
	private TextView TextViewCount;
	private Button theActiveButton;
	private Button theButtonClear;
	private Button theButtonEnter;
	private Button[] arrtheButtons = new Button[10];
	private Chronometer ChronometerStart;
	private EditText mEditor;
	private boolean isTimerStarted;
	private int intCounter;
	private int theDigitsPressed;
	private int[] arrintPrevButtons;
	private long lngElapsedTime;
        
    @Override
    public void onCreate(Bundle savedInstanceState) {
    	
    	arrintPrevButtons = new int[SMBGuesstheNumber.nDigits];
        super.onCreate(savedInstanceState);
        this.setTitle(getString(R.string.app_name) 
        		+ getString(R.string.abbr_version) 
        		+ getString(R.string.app_version));
        setContentView(R.layout.guessthenumber);
    	SetDisplayElements();
        StartaNewGame();
		(new CtrlMaintanence()).resumetheGame();
        if(SMBGuesstheNumber.isGameStarted)
        {
        	resumetheGame();
        }
        UpdateDisplayElements();
    }

    @Override
	protected void onPause(){
    	if(isTimerStarted)
    	{
    		SMBGuesstheNumber.lngElapsedTime = SystemClock.elapsedRealtime() - lngElapsedTime;
    	}
		super.onPause();
	}

    @Override
	protected void onResume(){
    	if(isTimerStarted)
    	{
    		lngElapsedTime = SystemClock.elapsedRealtime() - SMBGuesstheNumber.lngElapsedTime;
            ChronometerStart.setBase(lngElapsedTime);
    		ChronometerStart.start();
    	}
		super.onResume();
	}

    @Override
	protected void onDestroy(){
    	if(SMBGuesstheNumber.isGameStarted)
        {
			savetheGame();
        }
    	CtrlMaintanence ctrlMaintanence= new CtrlMaintanence();
    	ctrlMaintanence.savetheGame();
    	super.onDestroy();
	}
    
	@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        menu.add(0, NEWGAME_ID, 0, R.string.newgame).setShortcut('0', 'b');
        menu.add(0, SHOWMETHENUMBER_ID, 0, R.string.showmethenumber).setShortcut('1', 's');
        menu.add(0, ABOUT_ID, 0, R.string.about).setShortcut('1', 'a');
        menu.add(0, EXIT_ID, 0, R.string.exit).setShortcut('1', 'c');
        return true;
    }

	@Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case NEWGAME_ID:
            SMBGuesstheNumber.isGameStarted = false;
            StartaNewGame();
            return true;
        case SHOWMETHENUMBER_ID:
            SMBGuesstheNumber.isGameStarted = false;
            ShowmetheNumber();
            return true;
        case ABOUT_ID:
        	showDialog(R.id.display_hints);
        	return true;
        case EXIT_ID:
            finish();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
	public void onClick(View v) {
		switch(((Button) v).getId())
		{
		case R.id.enter:
			EntertheNumber();
			break;
		case R.id.clear:
			CleartheNumber();
			break;
		case R.id.number_zero:
		case R.id.number_one:
		case R.id.number_two:
		case R.id.number_three:
		case R.id.number_four:
		case R.id.number_five:
		case R.id.number_six:
		case R.id.number_seven:
		case R.id.number_eight:
		case R.id.number_nine:
			AddtotheNumber(mEditor, (Button) v);
			break;
		}
	}

    @Override
	protected Dialog onCreateDialog(int id) {
    	switch(id){
    	case R.id.display_success:
	        return new AlertDialog.Builder(GfxGuesstheNumber.this)
	        .setIcon(R.drawable.droid)
	        .setTitle(R.string.dialog_success)
	        .setPositiveButton(R.string.alert_dialog_newgame, new DialogInterface.OnClickListener() {
	            public void onClick(DialogInterface dialog, int whichButton) {
	            	StartaNewGame();
	            }
	        })
	        .setNegativeButton(R.string.exit, new DialogInterface.OnClickListener() {
	            public void onClick(DialogInterface dialog, int whichButton) {
	                finish();
	            }
	        })
	        .create();

    	case R.id.display_failure:
	        return new AlertDialog.Builder(GfxGuesstheNumber.this)
	        .setIcon(R.drawable.droid)
	        .setTitle(R.string.dialog_failure)
	        .setPositiveButton(R.string.alert_dialog_newgame, new DialogInterface.OnClickListener() {
	            public void onClick(DialogInterface dialog, int whichButton) {
	            	StartaNewGame();
	            }
	        })
	        .setNegativeButton(R.string.exit, new DialogInterface.OnClickListener() {
	            public void onClick(DialogInterface dialog, int whichButton) {
	                finish();
	            }
	        })
	        .create();

    	case R.id.display_flaglist:
    		AlertDialog listdialog = new AlertDialog.Builder(GfxGuesstheNumber.this)
    		.setIcon(R.drawable.droid)
    		.setTitle(R.string.dialog_flaglist)
    		.setItems(R.array.entries_flaglist, new DialogInterface.OnClickListener() {
    			public void onClick(DialogInterface dialog, int whichButton) {
    				SMBGuesstheNumber.arrintButtonStates
    				[Integer.parseInt(theActiveButton.getText().toString())] = whichButton;
    				switch(whichButton){
    				case 0:
    					theActiveButton.setTextColor(Color.BLACK);
    					break;    					
    				case 1:
    					theActiveButton.setTextColor(Color.GREEN);
    					break;
    				case 2:
    					theActiveButton.setTextColor(Color.YELLOW);
    					break;
    				case 3:
    					theActiveButton.setTextColor(Color.RED);
    					break;
    				}
    			}
    		})
    		.create();
    		return listdialog;
    	case R.id.display_hints:
            return new AlertDialog.Builder(this)
            .setIcon(R.drawable.droid)
            .setTitle(R.string.dialog_hint_title)
            .setMessage(R.string.dialog_hint_text)
            .setPositiveButton(R.string.OK, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int whichButton) {
                }
            })
            .create();
    	}
    	return null;
	}

    private void StartaNewGame(){
    	
    	CtrlGuesstheNumber ctrlGuesstheNumber = new CtrlGuesstheNumber();
    	
        SMBGuesstheNumber.theSecretNumber = ctrlGuesstheNumber.gettheSecretNumber();
        theDigitsPressed = 0;
        
		for(int i = 1; i < 10; i++)
		{
			arrtheButtons[i].setEnabled(true);
		}
        arrtheButtons[0].setEnabled(false);
        mEditor.setText("");
        mAdapter.clear();
        theButtonEnter.setEnabled(false);
        theButtonClear.setEnabled(false);
        lngElapsedTime = SystemClock.elapsedRealtime();
        ChronometerStart.setBase(lngElapsedTime);
        ChronometerStart.stop();
        isTimerStarted = false; 
        intCounter = 0;
		TextViewCount.setText(getString(R.string.totalshots)
				  + Integer.toString(intCounter)
				  );
    	for(int i = 0; i < 10; i++)
    	{
    		arrtheButtons[i].setTextColor(Color.BLACK);
    		SMBGuesstheNumber.arrintButtonStates[i] = 0;
    	}
    }
    
    private void ShowmetheNumber(){
    	mEditor.setText(SMBGuesstheNumber.theSecretNumber);
		for(int i = 0; i < 10; i++)
		{
			arrtheButtons[i].setEnabled(false);
		}
        theButtonEnter.setEnabled(false);
        theButtonClear.setEnabled(false);
        ChronometerStart.stop();
        isTimerStarted = false; 
    }

    private void AddtotheNumber(EditText theNumber, Button theButtonPressed) {

   		theNumber.append(theButtonPressed.getText().toString());
   		theButtonPressed.setEnabled(false);
		arrintPrevButtons[theDigitsPressed++] = Integer.parseInt(theButtonPressed.getText().toString());
		
		if(theNumber.getText().toString().length() == 1)
		{
			arrtheButtons[0].setEnabled(true);
			theButtonClear.setEnabled(true);
		}
    	
    	if(theNumber.getText().toString().length() == SMBGuesstheNumber.nDigits)
    	{
			for(int i = 0; i < 10; i++)
			{
				arrtheButtons[i].setEnabled(false);
			}
			theButtonEnter.setEnabled(true);
    	}
    	if(!isTimerStarted)
    	{
            lngElapsedTime = SystemClock.elapsedRealtime();
            ChronometerStart.setBase(lngElapsedTime);
    		ChronometerStart.start();
            isTimerStarted = true;
    	}
        SMBGuesstheNumber.isGameStarted = true;
    }
    
    private void CleartheNumber(){

    	mEditor.setText(mEditor.getText().toString().substring(0, mEditor.getText().toString().length() -1));
		if (mEditor.getText().toString().length() == SMBGuesstheNumber.nDigits - 1)
		{
			for(int i = 0; i < 10; i++)
			{
				arrtheButtons[i].setEnabled(true);
			}
			theDigitsPressed--;
			for(int i = 0; i < theDigitsPressed; i++)
			{
				arrtheButtons[arrintPrevButtons[i]].setEnabled(false);
			}
			theButtonEnter.setEnabled(false);
		}
		else
		{
			arrtheButtons[arrintPrevButtons[--theDigitsPressed]].setEnabled(true);
		}
		
		if(mEditor.getText().toString().length() == 0)
		{
			arrtheButtons[0].setEnabled(false);
			theButtonClear.setEnabled(false);
		}
    }
    
    private void EntertheNumber(){

    	CtrlGuesstheNumber ctrlGuesstheNumber = new CtrlGuesstheNumber();

    	int[] theResult = ctrlGuesstheNumber.ProcesstheNumber(mEditor.getText().toString());
		if(theResult[0] == SMBGuesstheNumber.nDigits && theResult[1] == 0)
		{
            SMBGuesstheNumber.isGameStarted = false;
			ChronometerStart.stop();
			isTimerStarted = false;
	    	vibrator.vibrate(100);
			showDialog(R.id.display_success);
		}
		mAdapter.add(getString(R.string.margin)
				+ getString(R.string.plus)
				+ theResult[0] 
				+ getString(R.string.minus) 
				+ theResult[1]
				+ getString(R.string.gap)
				+ mEditor.getText().toString()
				);
		mEditor.setText("");
		for(int i = 1; i < 10; i++)
		{
			arrtheButtons[i].setEnabled(true);
		}
		arrtheButtons[0].setEnabled(false);
		theDigitsPressed = 0;
		theButtonEnter.setEnabled(false);
		theButtonClear.setEnabled(false);
		intCounter++;
		TextViewCount.setText(getString(R.string.totalshots)
							  + Integer.toString(intCounter)
							  );

		if (SMBGuesstheNumber.nMaxShots != 0 && intCounter == SMBGuesstheNumber.nMaxShots)
		{
            SMBGuesstheNumber.isGameStarted = false;
	    	ShowmetheNumber();
	    	vibrator.vibrate(100);
			showDialog(R.id.display_failure);
		}
    }
    
    private void SetDisplayElements() {
    	
        mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, mStrings)
        {
            @Override 
            public View getView( int position, View convertView, ViewGroup parent ) 
            { 
                TextView txtView = new TextView(this.getContext()); 
                txtView.setTextSize(16); 
                txtView.setText(this.getItem(position));
                return txtView; 
            } 
        };
        
        setListAdapter(mAdapter);
        getListView().setTextFilterEnabled(true);
        mEditor = (EditText) findViewById(R.id.userText);
        TextViewCount = (TextView) findViewById(R.id.TextViewCount);
        ChronometerStart = (Chronometer) findViewById(R.id.ChronometerStart);
        vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
        arrtheButtons[0] = (Button) findViewById(R.id.number_zero);
        arrtheButtons[1] = (Button) findViewById(R.id.number_one);
        arrtheButtons[2] = (Button) findViewById(R.id.number_two);
        arrtheButtons[3] = (Button) findViewById(R.id.number_three);
        arrtheButtons[4] = (Button) findViewById(R.id.number_four);
        arrtheButtons[5] = (Button) findViewById(R.id.number_five);
        arrtheButtons[6] = (Button) findViewById(R.id.number_six);
        arrtheButtons[7] = (Button) findViewById(R.id.number_seven);
        arrtheButtons[8] = (Button) findViewById(R.id.number_eight);
        arrtheButtons[9] = (Button) findViewById(R.id.number_nine);
        theButtonEnter = (Button) findViewById(R.id.enter);
        theButtonClear = (Button) findViewById(R.id.clear);
        for(int i = 0; i < 10; i++)
        {
            arrtheButtons[i].setOnClickListener(this);
            arrtheButtons[i].setOnLongClickListener(this);
        }
        theButtonEnter.setOnClickListener(this);
        theButtonClear.setOnClickListener(this);
    }
    
    private void UpdateDisplayElements(){

    	if(SMBGuesstheNumber.bTotalShots)
        {
        	TextViewCount.setVisibility(View.VISIBLE);
        }
        else
        {
        	TextViewCount.setVisibility(View.INVISIBLE);
        }

        if(SMBGuesstheNumber.bElapsedTime)
        {
        	ChronometerStart.setVisibility(View.VISIBLE);
        }
        else
        {
        	ChronometerStart.setVisibility(View.INVISIBLE);
        }
        if(!SMBGuesstheNumber.bDisplayFlagList)
        {
        	for(int i = 0; i < 10; i++)
        	{
        		arrtheButtons[i].setTextColor(Color.BLACK);
        	}
        }
    }
    
    private void resumetheGame(){
        mEditor.setText(SMBGuesstheNumber.mEditorText);
        for(String strGuess: SMBGuesstheNumber.mStrings)
        {
        	mAdapter.add(strGuess);
        }
		intCounter = SMBGuesstheNumber.intCounter;
		theDigitsPressed = SMBGuesstheNumber.theDigitsPressed;
		arrintPrevButtons = SMBGuesstheNumber.arrintPrevButtons;

		for(int i = 0; i < 10; i++)
		{
			arrtheButtons[i].setEnabled(SMBGuesstheNumber.arrisButtonEnabled[i]);
			switch(SMBGuesstheNumber.arrintButtonStates[i]){
			case 0:
				arrtheButtons[i].setTextColor(Color.BLACK);
				break;    					
			case 1:
				arrtheButtons[i].setTextColor(Color.GREEN);
				break;
			case 2:
				arrtheButtons[i].setTextColor(Color.YELLOW);
				break;
			case 3:
				arrtheButtons[i].setTextColor(Color.RED);
				break;
			}
		}
		theButtonClear.setEnabled(SMBGuesstheNumber.arrisButtonEnabled[10]);
		theButtonEnter.setEnabled(SMBGuesstheNumber.arrisButtonEnabled[11]);
		TextViewCount.setText(getString(R.string.totalshots)
				  + Integer.toString(intCounter)
				  );
        isTimerStarted = true;
    }

    private void savetheGame(){

		SMBGuesstheNumber.mEditorText = mEditor.getText().toString();
		SMBGuesstheNumber.mStrings = mStrings;
		SMBGuesstheNumber.intCounter = intCounter;
		SMBGuesstheNumber.theDigitsPressed = theDigitsPressed;
		SMBGuesstheNumber.arrintPrevButtons = arrintPrevButtons;
		for(int i = 0; i < 10; i++)
		{
			SMBGuesstheNumber.arrisButtonEnabled[i] = arrtheButtons[i].isEnabled();
		}
		SMBGuesstheNumber.arrisButtonEnabled[10] = theButtonClear.isEnabled();
		SMBGuesstheNumber.arrisButtonEnabled[11] = theButtonEnter.isEnabled();
    }
    
    @Override
	public boolean onLongClick(View view) {
		if(SMBGuesstheNumber.bDisplayFlagList)
		{
			theActiveButton = (Button) view;
			showDialog(R.id.display_flaglist);
		}
		return false;
	}
}